package com.tsd.jxc.buy.entity;

import com.fasterxml.jackson.annotation.JsonFormat;
import com.tsd.core.constants.Constants;
import com.tsd.core.utils.DoubleUtil;
import com.tsd.core.utils.HlpUtils;
import com.tsd.core.utils.ListUtil;
import com.tsd.jxc.goods.entity.JxcGoodsPriceExt;
import com.tsd.jxc.stock.entity.JxcStockInbillItemExt;
import com.tsd.jxc.vo.JxcSettingVo;
import com.tsd.jxc.vo.PrintVo;
import io.swagger.annotations.ApiModel;

import java.io.Serializable;
import java.math.BigDecimal;
import java.util.Date;
import java.util.List;

/**
 * 采购订单-明细扩展
 *
 * @author Hillpool
 * @date 2022/07/29 15:00:45
 */
@ApiModel(description = "采购订单-明细扩展")
public class JxcBuyOrderDetailExt extends JxcBuyOrderDetail implements Serializable {

    private List<String> order_list;

    private List<String> sid_list;

    private String order_code;

    private String goods_code;

    private String goods_name;

    private String goods_spec;

    private String goods_model;

    private String goods_unit;

    private BigDecimal sale_price;

    private String supplier_name;

    private String supplier_code;

    private String supplier_short_name;

    private String supplier_display;

    private String supplier_contact_name;

    private String supplier_contact_phone;
    //以销定购的销售单列表，每个数据的格式是：<sale_order_sid>_<sale_order_detail_sid>
    private List<String> sale_order_detail_list;

    private Integer gen_bill_num;

    private BigDecimal gen_buy_qty;

    private BigDecimal gen_buy_qty4base;

    private BigDecimal sale_order_detail_qty;

    private String sale_order_code;

    private String client_name;

    private String client_code_join;

    private String client_short_name;

    private String client_display;

    private BigDecimal send_detail_qty;

    private Long send_detail_id;

    @JsonFormat(pattern = "yyyy-MM-dd", locale = "zh", timezone = "GMT+8")
    private Date order_date;

    @JsonFormat(pattern = "yyyy-MM-dd", locale = "zh", timezone = "GMT+8")
    private Date send_date;

    private String new_return_order;

    private String contain_tax;

    private BigDecimal supplier_price_per_m2;

    private BigDecimal supplier_price;

    private BigDecimal supplier_amount;

    private String contract_code;

    private BigDecimal engineering_fee;

    private BigDecimal test_frame_fee;

    private BigDecimal flight_test_fee;

    private String shipping_date_str;

    private Integer order_audit_state;

    private List<JxcGoodsPriceExt> price_list;
    //当前单位与基本单位的换算数量
    private BigDecimal unit_qty;

    private BigDecimal remain_qty4base;

    public List<String> getOrder_list() {
        return order_list;
    }

    public void setOrder_list(List<String> order_list) {
        this.order_list = order_list;
    }

    public List<String> getSid_list() {
        return sid_list;
    }

    public void setSid_list(List<String> sid_list) {
        this.sid_list = sid_list;
    }

    public String getOrder_code() {
        return order_code;
    }

    public void setOrder_code(String order_code) {
        this.order_code = order_code;
    }

    public String getGoods_code() {
        return goods_code;
    }

    public void setGoods_code(String goods_code) {
        this.goods_code = goods_code;
    }

    public String getGoods_name() {
        return goods_name;
    }

    public void setGoods_name(String goods_name) {
        this.goods_name = goods_name;
    }

    public String getGoods_unit() {
        return goods_unit;
    }

    public void setGoods_unit(String goods_unit) {
        this.goods_unit = goods_unit;
    }

    public BigDecimal getSale_price() {
        return sale_price;
    }

    public void setSale_price(BigDecimal sale_price) {
        this.sale_price = sale_price;
    }

    public String getSupplier_name() {
        return supplier_name;
    }

    public void setSupplier_name(String supplier_name) {
        this.supplier_name = supplier_name;
    }

    public String getSupplier_code() {
        return supplier_code;
    }

    public void setSupplier_code(String supplier_code) {
        this.supplier_code = supplier_code;
    }

    public String getSupplier_short_name() {
        return supplier_short_name;
    }

    public void setSupplier_short_name(String supplier_short_name) {
        this.supplier_short_name = supplier_short_name;
    }

    public String getSupplier_display() {
        return supplier_display;
    }

    public void setSupplier_display(String supplier_display) {
        this.supplier_display = supplier_display;
    }

    public String getSupplier_contact_name() {
        return supplier_contact_name;
    }

    public void setSupplier_contact_name(String supplier_contact_name) {
        this.supplier_contact_name = supplier_contact_name;
    }

    public String getSupplier_contact_phone() {
        return supplier_contact_phone;
    }

    public void setSupplier_contact_phone(String supplier_contact_phone) {
        this.supplier_contact_phone = supplier_contact_phone;
    }

    public List<String> getSale_order_detail_list() {
        return sale_order_detail_list;
    }

    public void setSale_order_detail_list(List<String> sale_order_detail_list) {
        this.sale_order_detail_list = sale_order_detail_list;
    }

    public Integer getGen_bill_num() {
        return gen_bill_num;
    }

    public void setGen_bill_num(Integer gen_bill_num) {
        this.gen_bill_num = gen_bill_num;
    }

    public BigDecimal getGen_buy_qty() {
        return gen_buy_qty;
    }

    public void setGen_buy_qty(BigDecimal gen_buy_qty) {
        this.gen_buy_qty = gen_buy_qty;
    }

    public BigDecimal getGen_buy_qty4base() {
        return gen_buy_qty4base;
    }

    public void setGen_buy_qty4base(BigDecimal gen_buy_qty4base) {
        this.gen_buy_qty4base = gen_buy_qty4base;
    }

    public BigDecimal getSale_order_detail_qty() {
        return sale_order_detail_qty;
    }

    public void setSale_order_detail_qty(BigDecimal sale_order_detail_qty) {
        this.sale_order_detail_qty = sale_order_detail_qty;
    }

    public String getSale_order_code() {
        return sale_order_code;
    }

    public void setSale_order_code(String sale_order_code) {
        this.sale_order_code = sale_order_code;
    }

    public String getClient_name() {
        return client_name;
    }

    public void setClient_name(String client_name) {
        this.client_name = client_name;
    }

    public String getClient_code_join() {
        return client_code_join;
    }

    public void setClient_code_join(String client_code_join) {
        this.client_code_join = client_code_join;
    }

    public String getClient_short_name() {
        return client_short_name;
    }

    public void setClient_short_name(String client_short_name) {
        this.client_short_name = client_short_name;
    }

    public String getClient_display() {
        return client_display;
    }

    public void setClient_display(String client_display) {
        this.client_display = client_display;
    }

    public BigDecimal getSend_detail_qty() {
        return send_detail_qty;
    }

    public void setSend_detail_qty(BigDecimal send_detail_qty) {
        this.send_detail_qty = send_detail_qty;
    }

    public Long getSend_detail_id() {
        return send_detail_id;
    }

    public void setSend_detail_id(Long send_detail_id) {
        this.send_detail_id = send_detail_id;
    }

    public Date getOrder_date() {
        return order_date;
    }

    public void setOrder_date(Date order_date) {
        this.order_date = order_date;
    }

    public Date getSend_date() {
        return send_date;
    }

    public void setSend_date(Date send_date) {
        this.send_date = send_date;
    }

    public String getNew_return_order() {
        return new_return_order;
    }

    public void setNew_return_order(String new_return_order) {
        this.new_return_order = new_return_order;
    }

    public String getContain_tax() {
        return contain_tax;
    }

    public void setContain_tax(String contain_tax) {
        this.contain_tax = contain_tax;
    }

    public BigDecimal getSupplier_price_per_m2() {
        return supplier_price_per_m2;
    }

    public void setSupplier_price_per_m2(BigDecimal supplier_price_per_m2) {
        this.supplier_price_per_m2 = supplier_price_per_m2;
    }

    public BigDecimal getSupplier_price() {
        return supplier_price;
    }

    public void setSupplier_price(BigDecimal supplier_price) {
        this.supplier_price = supplier_price;
    }

    public BigDecimal getSupplier_amount() {
        return supplier_amount;
    }

    public void setSupplier_amount(BigDecimal supplier_amount) {
        this.supplier_amount = supplier_amount;
    }

    public String getContract_code() {
        return contract_code;
    }

    public void setContract_code(String contract_code) {
        this.contract_code = contract_code;
    }

    public BigDecimal getEngineering_fee() {
        return engineering_fee;
    }

    public void setEngineering_fee(BigDecimal engineering_fee) {
        this.engineering_fee = engineering_fee;
    }

    public BigDecimal getTest_frame_fee() {
        return test_frame_fee;
    }

    public void setTest_frame_fee(BigDecimal test_frame_fee) {
        this.test_frame_fee = test_frame_fee;
    }

    public BigDecimal getFlight_test_fee() {
        return flight_test_fee;
    }

    public void setFlight_test_fee(BigDecimal flight_test_fee) {
        this.flight_test_fee = flight_test_fee;
    }

    public String getShipping_date_str() {
        return shipping_date_str;
    }

    public void setShipping_date_str(String shipping_date_str) {
        this.shipping_date_str = shipping_date_str;
    }

    public Integer getOrder_audit_state() {
        return order_audit_state;
    }

    public void setOrder_audit_state(Integer order_audit_state) {
        this.order_audit_state = order_audit_state;
    }

    public List<JxcGoodsPriceExt> getPrice_list() {
        return price_list;
    }

    public void setPrice_list(List<JxcGoodsPriceExt> price_list) {
        this.price_list = price_list;
    }

    public String getGoods_spec() {
        return goods_spec;
    }

    public void setGoods_spec(String goods_spec) {
        this.goods_spec = goods_spec;
    }

    public String getGoods_model() {
        return goods_model;
    }

    public void setGoods_model(String goods_model) {
        this.goods_model = goods_model;
    }

    public BigDecimal getRemain_qty4base() {
        return remain_qty4base;
    }

    public void setRemain_qty4base(BigDecimal remain_qty4base) {
        this.remain_qty4base = remain_qty4base;
    }

    public BigDecimal getUnit_qty() {
        return unit_qty;
    }

    public void setUnit_qty(BigDecimal unit_qty) {
        this.unit_qty = unit_qty;
    }

    public void calcUnitQty(BigDecimal qty4baseBig, BigDecimal qtyBig) {
        double qty4base = qty4baseBig == null ? 0D : qty4baseBig.doubleValue();
        double qty = qtyBig == null ? 0D : qtyBig.doubleValue();
        double unitQty = DoubleUtil.div(qty4base, qty, 4);
        this.setUnit_qty(BigDecimal.valueOf(unitQty));
    }

    public BigDecimal getTotal_price() {
        double price = DoubleUtil.div(this.getTotal_amount().doubleValue(), this.getQty().doubleValue(), 4);
        return BigDecimal.valueOf(price);
    }

    public void calcGoodsPrice() {
        List<JxcGoodsPriceExt> priceExtList = this.getPrice_list();
        if (!HlpUtils.isEmptyList(priceExtList)) {
            JxcGoodsPriceExt unitPriceExt = ListUtil.get(priceExtList, t -> t.getUnit_name().equals(this.getUnit_name()));
            if (unitPriceExt != null) {
                this.setUnit_qty(BigDecimal.valueOf(unitPriceExt.getQty()));
                if (HlpUtils.isEmpty(this.getQty4base())) {
                    this.setQty4base(BigDecimal.valueOf(DoubleUtil.mul(this.getQty(), unitPriceExt.getQty())));
                }
            }
            double baseUnitPrice = DoubleUtil.div(this.getAmount(), this.getQty4base(), 4);
            for (JxcGoodsPriceExt priceExt : priceExtList) {
                priceExt.setBuy_price(BigDecimal.valueOf(DoubleUtil.mul(baseUnitPrice, priceExt.getQty())));
            }
            this.setPrice_list(priceExtList);
        }
    }

    public JxcBuyReturnBillDetailExt genReturnBillDetail() {
        JxcBuyReturnBillDetailExt detailExt = new JxcBuyReturnBillDetailExt();
        detailExt.setBuy_order_sid(this.getOrder_sid());
        detailExt.setBuy_detail_sid(this.getSid());
        detailExt.setGoods_sid(this.getGoods_sid());
        detailExt.calcUnitQty(this.getQty4base(), this.getQty());
        // 剩余基本数量换算单位数量
        double qty = DoubleUtil.div(this.getRemain_qty4base(), detailExt.getUnit_qty(), 3);
        detailExt.setQty(BigDecimal.valueOf(qty));
        detailExt.setQty4base(this.getRemain_qty4base());
        detailExt.setRemain_qty4base(this.getRemain_qty4base());
        // 计算未退货金额
        double amount = this.getTotal_amount().doubleValue();
        if (!HlpUtils.isEmpty(this.getReturn_amount())) {
            amount = DoubleUtil.sub(amount, this.getReturn_amount());
        }
        detailExt.setAmount(BigDecimal.valueOf(amount));
        // 计算单位单价
        detailExt.setPrice(BigDecimal.valueOf(DoubleUtil.div(amount, qty, 4)));
        detailExt.setOut_bill(Constants.DR_VALID);
        detailExt.setUnit_name(this.getUnit_name());
        detailExt.setGoods_name(this.getGoods_name());
        detailExt.setOrder_code(this.getOrder_code());
        detailExt.setSn(this.getSn());
        detailExt.setGoods_spec(this.getGoods_name());
        // 根据未退货金额及剩余基本数量计算价格
        double baseUnitPrice = DoubleUtil.div(amount, this.getRemain_qty4base(), 3);
        List<JxcGoodsPriceExt> priceExtList = ListUtil.copyList(this.getPrice_list(), JxcGoodsPriceExt.class);
        if (!HlpUtils.isEmptyList(priceExtList)) {
            for (JxcGoodsPriceExt priceExt : priceExtList) {
                double price = DoubleUtil.mul(baseUnitPrice, priceExt.getQty());
                priceExt.setBuy_price(BigDecimal.valueOf(price));
            }
        }
        detailExt.setPrice_list(priceExtList);
        return detailExt;
    }

    public JxcStockInbillItemExt genInBillItem() {
        JxcStockInbillItemExt itemExt = new JxcStockInbillItemExt();
        itemExt.setGoods_sid(this.getGoods_sid());
        itemExt.setSrc_sid(this.getSid());
        itemExt.setPrice(this.getTotal_price());
        itemExt.setIn_qty(this.getQty());
        itemExt.setAmount(this.getTotal_amount());
        itemExt.setUnit_name(this.getGoods_unit());
        itemExt.setGoods_name(this.getGoods_name());
        itemExt.setSn(this.getSn());
        return itemExt;
    }

    public PrintVo convert2Print() {
        PrintVo vo = new PrintVo();
        vo.setSn(this.getSn());
        vo.setGoods_name(this.getGoods_name());
        vo.setQty(this.getQty());
        vo.setAmount(this.getAmount());
        vo.setNote_info(this.getNote_info());
        vo.setReturn_qty(this.getReturn_qty());
        vo.setReturn_amount(this.getReturn_amount());
        return vo;
    }

    /**
     * 计算价格、金额、税额、合计金额
     *
     * @param orderExt
     * @param settingVo
     * @param basePrice 是否以价格计算金额
     */
    public void calc(JxcBuyOrderExt orderExt, JxcSettingVo settingVo, boolean basePrice) {
        if (HlpUtils.isEmpty(this.getTax_rate())) {
            this.setTax_rate(settingVo.getDefault_tax_ratio());
        }
        if (orderExt != null) {
            if (!HlpUtils.isEmpty(orderExt.getTax_rate())) {
                this.setTax_rate(orderExt.getTax_rate());
            }
            if (!HlpUtils.isEmpty(orderExt.getInvoice_type())) {
                this.setTax_rate(orderExt.getInvoice_type() > 0 ? this.getTax_rate() : BigDecimal.ZERO);
            }
        }
        if (basePrice) {
            if (HlpUtils.isAllNotEmpty(this.getQty(), this.getPrice())) {
                double amount = DoubleUtil.mul(this.getQty(), this.getPrice());
                this.setAmount(BigDecimal.valueOf(amount));
            }
        } else {
            if (HlpUtils.isAllNotEmpty(this.getQty(), this.getAmount())) {
                double price = DoubleUtil.div(this.getAmount().doubleValue(), this.getQty().doubleValue(), 6);
                this.setPrice(BigDecimal.valueOf(price));
            }
        }
        this.setTax_amount(BigDecimal.ZERO);
        if (HlpUtils.isAllNotEmpty(this.getAmount(), this.getTax_rate())) {
            this.setTax_amount(settingVo.getTaxAmount(this.getAmount(), this.getTax_rate(), false));
        }
        double totalAmount = DoubleUtil.add(this.getAmount(), this.getTax_amount());
        this.setTotal_amount(BigDecimal.valueOf(totalAmount));
    }
}
